import xlrd
import datetime
import openpyxl
import pandas as pd
import xlrd
import xlwt

def ProblemlishCheck():

    row_max = 0
    
    # *************************************************合并问题清单
    problem_list_all = pd.DataFrame()

    # 读取表格，并删除全空行，减小内存占用
    problem_list_frotend = pd.read_excel("D:\\5.大众品牌周报\\0.1问题清单\\前端-大众.xlsx", skiprows=1)
    problem_list_frotend.dropna(axis=0, how="all", inplace=True)  # 删除全空的值

    problem_list_heckend = pd.read_excel("D:\\5.大众品牌周报\\0.1问题清单\\后端-大众.xlsx", skiprows=1)
    problem_list_heckend.dropna(axis=0, how="all", inplace=True)  # 删除全空的值

    problem_list_ture = pd.read_excel("D:\\5.大众品牌周报\\0.1问题清单\\车门-大众.xlsx", skiprows=1)
    problem_list_ture.dropna(axis=0, how="all", inplace=True)  # 删除全空的值

    problem_list_innen = pd.read_excel("D:\\5.大众品牌周报\\0.1问题清单\\内外饰-大众.xlsx", skiprows=1)
    problem_list_innen.dropna(axis=0, how="all", inplace=True)  # 删除全空的值

    print("文件读取成功！")

    # 筛选并值保留有效数据
    problem_list_frotend = problem_list_frotend[problem_list_frotend['问题描述\nProbleme'].notna()]
    problem_list_heckend = problem_list_heckend[problem_list_heckend['问题描述\nProbleme'].notna()]
    problem_list_ture = problem_list_ture[problem_list_ture['问题描述\nProbleme'].notna()]
    problem_list_innen = problem_list_innen[problem_list_innen['问题描述\nProbleme'].notna()]

    print("文件有效内容筛选完成！")

    # 合并并进行输出
    problem_list_all = pd.concat([problem_list_frotend, problem_list_heckend, problem_list_ture, problem_list_innen])

    problem_list_all.to_excel("D:\\5.大众品牌周报\\0.1问题清单\\清单合并-大众.xlsx", index=False)
    print("合并后问题清单已建立！")

    row_max = problem_list_all.shape[0]

    # 读入工作簿，并获取工作表
    workbook = xlrd.open_workbook("D:\\5.大众品牌周报\\0.1问题清单\\清单合并-大众.xlsx")  # 打开“测试表格”，地址赋值给“workbook”
    worksheet = workbook.sheet_by_index(0)  # 将工作簿"workbook"的第0个工作表激活，赋值给“worksheet"
    print("合并后问题清单读取成功，开始检查")
    print("检查结果如下：")

    rows = 1  # 从excel表的第3行开始工作
    # 获取相同问题的启示行和结束行
    row_start = 1
    row_end = 1
    time_nod = []  # 时间节点列表
    measures = []  # 措施列表
    relation_01 = {}  # 时间与措施对应字典
    res_department = ['PS', 'BS', 'QA', 'VSC', 'PA', 'CA', 'IE', 'TE', 'PL']

    while worksheet.cell_value(rows, 3) != "" and worksheet.cell_value(rows + 1, 3) != "":  # while循环实现，遍历所有行至倒数第二行

        # 大if模块，用于找到同一问题
        if "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                    str(worksheet.cell_value(rows, 2))]) \
                == \
                "".join([str(int(worksheet.cell_value(rows + 1, 0))), str(worksheet.cell_value(rows + 1, 1)),
                         str(worksheet.cell_value(rows + 1, 2))]):
            # 问题检查模块1：同问题，不同状态检查
            if worksheet.cell_value(rows, 16) != worksheet.cell_value(rows + 1, 16):
                print("相同问题，不同状态错误！错误问题为：", \
                      "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                               str(worksheet.cell_value(rows, 2))]))

            # 问题检查模块2：同一问题，提出时间不一致
            if worksheet.cell_value(rows, 6) != worksheet.cell_value(rows + 1, 6):
                print("相同问题，不同提出日期！错误问题为：", \
                      "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                               str(worksheet.cell_value(rows, 2))]))
            # 问题检查模块3：同一问题，分析完成时间不一致
            if worksheet.cell_value(rows, 18) != worksheet.cell_value(rows + 1, 18):
                print("相同问题，不同分析完成时间！错误问题为：", \
                      "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                               str(worksheet.cell_value(rows, 2))]))

            # 问题检查模块4：同一问题，销项时间不一致
            if worksheet.cell_value(rows, 19) != worksheet.cell_value(rows + 1, 19):
                print("相同问题，不同销项时间！错误问题为：", \
                      "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                               str(worksheet.cell_value(rows, 2))]))

            # 问题检查模块5：同一问题，措施序号中填写的措施总数不一致！

            if worksheet.cell_value(rows, 10)[0] != worksheet.cell_value(rows + 1, 10)[0]:
                print("相同问题，措施序号中填写的措施总数不一致！错误问题为：", \
                      "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                               str(worksheet.cell_value(rows, 2))]))

        rows += 1  # while循环实现，遍历所有行
        if rows > (row_max - 1):
            break

    rows = 1  # 从excel表的第2行开始遍历
    while worksheet.cell_value(rows, 3) != "":

        # 问题检查模块4：分析周期为负
        if isinstance(worksheet.cell_value(rows, 35), str) != 1:
            if worksheet.cell_value(rows, 35) < 0:
                print("分析周期为负！错误问题为：", \
                      "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                               str(worksheet.cell_value(rows, 2))]))

            # 问题检查模块5：分析周期过长
            if worksheet.cell_value(rows, 35) > 30:
                print("分析周期过长，检查下！错误问题为：", \
                      "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                               str(worksheet.cell_value(rows, 2))]))

        # 问题检查模块：分析完成周期为空
        if worksheet.cell_value(rows, 35) == "":
            print("分析周期为空！错误问题为：", \
                  "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                           str(worksheet.cell_value(rows, 2))]))

        # 问题检查模块6：问题状态错误
        if worksheet.cell_value(rows, 16) != 3 and worksheet.cell_value(rows, 16) != 5:
            print("问题状态错误！错误问题为：", \
                  "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                           str(worksheet.cell_value(rows, 2))]))

        # 问题检查模块：分析完成时间为空检查
        if worksheet.cell_value(rows, 18) == "":
            print("分析完成日期不可为空！错误问题为：", \
                  "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                           str(worksheet.cell_value(rows, 2))]))

        # 问题检查模块：已关闭问题，销项日期为空
        if worksheet.cell_value(rows, 16) == 5 and worksheet.cell_value(rows, 19) == "":
            print("销项日期为空！错误问题为：", \
                  "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                           str(worksheet.cell_value(rows, 2))]))

        # 问题检查模块7：措施拖期检查

        # 第一步：实现获取今天按照excel方式的时间戳
        date_start = datetime.datetime(1899, 12, 30)  # excel表起始日期1900年1月1日
        date_now = datetime.datetime.now()  # 当前时间
        today = date_now - date_start  # 今天距离1900年1月1日时间
        today_excel = today.days  # 转化为距离1900年1月1日天数，按照excel方式计算的时间戳

        # 第二步：判断表格中时间和今天的时间前后关系

        if worksheet.cell_value(rows, 11) != "":

            if worksheet.cell_value(rows, 14) != 5 and worksheet.cell_value(rows, 14) > 2:

                if str(worksheet.cell_value(rows, 11))[0].upper() != "O":
                    try:
                        if worksheet.cell_value(rows, 11) < today_excel:
                            print("问题措施拖期！错误问题为：", \
                                  "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                                           str(worksheet.cell_value(rows, 2))]))
                    except:
                        print(worksheet.cell_value(rows, 11))
        else:
            print("措施期限缺失！错误问题为：", \
                  "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                           str(worksheet.cell_value(rows, 2))]))

        # 问题检查模块9：措施格式检查

        if worksheet.cell_value(rows, 10) != "" and worksheet.cell_value(rows, 10)[0] != "\n" and \
                worksheet.cell_value(rows, 14) > 2:

            if worksheet.cell_value(rows, 10)[1] == "/":

                if int(worksheet.cell_value(rows, 10)[0]) < int(worksheet.cell_value(rows, 10)[2]):
                    print("措施格式错误！错误问题为：", \
                          "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                                   str(worksheet.cell_value(rows, 2))]))

            # 问题检查模块9：措施格式检查接上方
            else:

                print("措施格式错误！错误问题为：", \
                      "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                               str(worksheet.cell_value(rows, 2))]))

        # 问题检查模块：问题状态检查

        if worksheet.cell_value(rows, 14) >= 3:
            if worksheet.cell_value(rows, 10) == "" or worksheet.cell_value(rows, 10) == "\n":
                print("问题状态错误！错误问题为：", \
                      "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                               str(worksheet.cell_value(rows, 2))]))

        if res_department.count(worksheet.cell_value(rows, 12)) < 1:
            print("责任部门缩写错误或空缺！错误问题为：", \
                  "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 2))]), end='\t')
            print("正确缩写为（大写）：'PS','BS','QA','VSC','PA','CA','IE','TE','PL'")

        rows += 1  # while循环实现，遍历所有行
        if rows > row_max:
            break

    # 模块10：措施序号顺序检查

    # while循环实现，遍历所有行
    rows = 1
    while worksheet.cell_value(rows, 3) != "" and worksheet.cell_value(rows + 1, 3) != "":

        # if语句通过“\"实现了换行代码书写，减少变量操作，节省时间
        # if语句实现重复问题过滤,获取问题的起始行，和结束行
        if "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                    str(worksheet.cell_value(rows, 2))]) \
                != \
                "".join([str(int(worksheet.cell_value(rows + 1, 0))), str(worksheet.cell_value(rows + 1, 1)),
                         str(worksheet.cell_value(rows + 1, 2))]) \
                :
            row_end = rows  # 找到相同问题的最后一行

            # 获取开始行和结束行后直接进行判断进行判断语句
            for rows2 in range(row_start, row_end + 1):

                # 保证格式正确，防止转换出错

                if worksheet.cell_value(rows2, 14) > 2 and worksheet.cell_value(rows2, 10)[1] == "/":
                    measures.append(
                        float(worksheet.cell_value(rows2, 10)[0]) / float(worksheet.cell_value(rows2, 10)[2]))  # 形成措施列表
                    time_nod.append(worksheet.cell_value(rows2, 11))  # 形成时间节点列表

            relation_01 = dict(zip(measures, time_nod))  # 形成二者对应字典

            # 比较最后时间的序号，对应的时间是否为最靠后时间是
            try:
                if measures != []:
                    if relation_01[min(measures)] != max(time_nod):
                        print("措施序号顺序错误！错误问题为：", \
                              "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                                       str(worksheet.cell_value(rows, 2))]))
                elif int(worksheet.cell_value(rows2, 14)) > 2:
                    print("措施状态错误！错误问题为：", \
                          "".join([str(int(worksheet.cell_value(rows2, 0))), str(worksheet.cell_value(rows, 1)),
                                   str(worksheet.cell_value(rows2, 2))]))
            except:
                print("测试行，请忽略！")

            row_start = row_end + 1  # 确认一个问题的启示行后，直接确认下一个问题的开始行

        # 针对最后一行无法遍历的问题，单独进行判断
        if worksheet.cell_value(rows + 2, 3) == "":
            row_end = rows + 1

            # 进行判断语句
            for rows2 in range(row_start, row_end + 1):
                time_nod.append(worksheet.cell_value(rows2, 11))  # 形成时间节点列表
                measures.append(
                    float(worksheet.cell_value(rows2, 10)[0]) / float(worksheet.cell_value(rows2, 10)[2]))  # 形成措施列表

            relation_01 = dict(zip(measures, time_nod))  # 形成二者对应字典

            # 比较最后时间的序号，对应的时间是否为最靠后时间是

            if relation_01[min(measures)] != max(time_nod):
                print("问题序号顺序错误！错误问题为：", \
                      "".join([str(int(worksheet.cell_value(rows, 0))), str(worksheet.cell_value(rows, 1)),
                               str(worksheet.cell_value(rows, 2))]))

        time_nod = []  # 时间节点列表
        measures = []  # 措施列表
        relation_01 = {}  # 时间与措施对应字典

        rows += 1  # while循环实现，遍历所有行
        if rows > (row_max - 2):
            break

    print("检查结束！")
